# -*- coding:utf-8 -*-

import os
import sys
import time
import thread
import shutil
import threading

from MutexList import MutexList
from MyLogger import MyLogger, TIMEROTATE, SIZEROTATE
from MyException import Error, NoKeyError, CopyFileError
from StatLog import StatLog

#定义PATH模块
class PathClient(threading.Thread):
    def __init__(self, profile, adv_conf_list, pathinfo, statinfo_map):
        """
        初始化
        """
        #初始化线程模块
        threading.Thread.__init__(self)
        #初始化PATH接口信息
        self.name = pathinfo.name
        self.tmp_dir = pathinfo.tmp_dir
        self.dst_dir = pathinfo.dst_dir
        #初始化待发送文件目录
        self.send_dir = profile.send_dir
        #初始化统计日志开关
        self.is_write_statlog = False
        #初始化统计日志流向
        self.data_dest = pathinfo.name
        #初始化统计日志信息
        self.statinfo_map = statinfo_map
        #初始化重命名功能列表
        self.rename_func_list = []
        #初始化高级应用
        for adv_conf_name in pathinfo.adv_conf:
            if adv_conf_name.find("_RENAME_") > -1:
                for adv_conf in adv_conf_list:
                    if adv_conf.app_name == adv_conf_name:
                        self.rename_func_list.append((adv_conf.old_keyword, adv_conf.new_keyword))
            elif adv_conf_name.find("_STATLOG_") > -1:
                for adv_conf in adv_conf_list:
                    if adv_conf.app_name == adv_conf_name:
                        self.is_write_statlog = profile.is_write_statlog
                        self.data_dest = adv_conf.data_dest
            else:
                pass
        #print "---->", len(self.rename_func_list), "<----" 
        #初始化文件列表
        self.receive_file_list = MutexList()
        self.send_file_list = MutexList()
        #初始化日志
        self.success_logger = MyLogger(os.path.join(profile.log_dir, pathinfo.name + "_success.log"), SIZEROTATE, profile.size_rotate_backup_num)
        self.error_logger = MyLogger(os.path.join(profile.log_dir, pathinfo.name + "_error.log"), SIZEROTATE, profile.size_rotate_backup_num)
        #初始化统计日志
        self.statlog = None
        if self.is_write_statlog:
            self.statlog = StatLog(profile.statlog_dir, True)
            self.statlog.daemon = True
            self.statlog.start()
        #初始化备份目录
        self.backup_dir = os.path.join(profile.file_backup_dir, self.name)
        if not os.path.exists(self.backup_dir):
            os.makedirs(self.backup_dir)
        
    def run(self):
        """
        PATH模块函数主体
        """
        while(True):
            try:
                #获取所有待处理文件
                file_list = self.receive_file_list.get_all()
                #逐一处理每个文件
                for filename in file_list:
                    try:
                        try:
                            #文件重命名
                            tmp_filename = filename
                            for rename in self.rename_func_list:
                                #print rename[0], rename[1]
                                tmp_filename = tmp_filename.replace(rename[0], rename[1])
                            #拼接文件名
                            src_file = os.path.join(self.send_dir, filename)
                            tmp_file = os.path.join(self.tmp_dir, tmp_filename + ".temp")
                            dst_file = os.path.join(self.dst_dir, tmp_filename)
                            #获取统计日志信息
                            statinfo = self.statinfo_map.find(filename)
                            #拷贝文件到本地目录
                            try:
                                #拷贝文件到临时目录
                                shutil.copyfile(src_file, tmp_file)
                                #重命名文件到目的目录
                                os.rename(tmp_file, dst_file)
                                #将文件加入已处理文件列表
                                self.send_file_list.add(filename)
                                #记录程序日志
                                self.success_logger.info("Success copy file: %s size: %s record: %s to dir: %s"%(filename, statinfo.file_size, statinfo.record_num, self.dst_dir))
                                #写统计日志
                                if self.is_write_statlog:
                                    self.statlog.write_statlog_amply(filename, statinfo, 0, self.name, self.data_dest)
                            except Exception, msg:
                                #删除临时文件
                                if os.path.exists(tmp_file): 
                                    os.remove(tmp_file)
                                raise CopyFileError(msg)
                        except NoKeyError, msg:
                            self.error_logger.exception("Error copy file: %s size: 0 record: 0 to dir: %s cause: StatLog"%(filename, self.dst_dir))
                            if self.is_write_statlog:
                                self.statlog.write_statlog_curtly(filename, 0, "--", -1, self.name, self.data_dest)
                            raise
                        except CopyFileError, msg:
                            self.error_logger.exception("Error copy file: %s size: %s record: %s to dir: %s cause: CopyFile\n"%(filename, statinfo.file_size, statinfo.record_num, self.dst_dir))
                            if self.is_write_statlog:
                                self.statlog.write_statlog_amply(filename, statinfo, -1, self.name, self.data_dest)
                            raise
                        except Exception, msg:
                            self.error_logger.exception("Error copy file: %s size: 0 record: 0 to dir: %s cause: Unknown\n"%(filename, self.dst_dir))
                            if self.is_write_statlog:
                                self.statlog.write_statlog_amply(filename, statinfo, -1, self.name, self.data_dest)
                            raise Error(msg)
                                                                         
                    except Error, msg:
                        try:
                            #创建备份目录
                            sub_backup_dir = os.path.join(self.backup_dir, time.strftime("%Y%m%d%H",time.localtime()))
                            if not os.path.exists(sub_backup_dir):
                                os.makedirs(sub_backup_dir)
                            #备份文件
                            dst_file = os.path.join(sub_backup_dir, tmp_filename)
                            shutil.copyfile(src_file, dst_file)
                        except:
                            self.error_logger.exception("unknown error")
                        #将文件加入已处理文件列表
                        self.send_file_list.add(filename)

            except:
                self.error_logger.exception("unknown error")
                raise
                
            time.sleep(2)
                    
import unittest
import ConfigInfo 
import ConfigReader 
import ConfigAssist 
import StatInfo
import MutexMap

class PathClientTestCase(unittest.TestCase):
    def setUp(self):
        pass
    
    def tearDown(self):
        pass
    
    def testBaseFun(self):
        profile = ConfigReader.ConfigReader().read_profile()
        profile.is_write_statlog = True
        
        statlog_info = ConfigInfo.StatLog()
        statlog_info.app_name = "STATLOG_111"
        statlog_info.data_dest = "CB"
        
        pathinfo = ConfigInfo.PathInfo()
        pathinfo.tmp_dir = "../tmp"
        pathinfo.dst_dir = "../dst"
        pathinfo.name = "test"
        pathinfo.adv_conf.append(statlog_info.app_name)
        
        statinfo = StatInfo.StatInfo()
        statinfo.uparea_id = "320100"
        statinfo.protype_desc = "HTTP"
        statinfo.data_source = "111"
        statinfo.file_type = "bcp"
        statinfo.file_size = "1024"
        statinfo.record_num = "10000"
        
        filename = "MASS_1234567890_123456_HTTP_320100_111.bcp"
        fp = open(os.path.join(profile.send_dir, filename), "w")
        fp.write("ddddddddddddd")
        fp.close()
        
        statlog_map = MutexMap.MutexMap()
#        statlog_map.insert(filename, statinfo)
        path_client = PathClient(profile, [statlog_info], pathinfo, statlog_map)
        path_client.daemon = True
        path_client.start()
        
        path_client.receive_file_list.add(filename)
        time.sleep(5)
        print ", ".join(path_client.send_file_list.copy())
      
if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(PathClientTestCase("testBaseFun"))   
    runner = unittest.TextTestRunner()
    runner.run(suite)      
                            
        
    
